MCVE
https://github.com/hyperbotauthor/minvue3cliapp
MCVE en vivo
https://codesandbox.io/s/white-browser-fl7ji
Tengo una aplicación de servicio de CLI Vue 3, que usa componentes API de composición con ranuras.
El componente HelloWorld representa las ranuras que recibe en un div :
// src/components/Helloworld.js import { defineComponent, h } from "vue"; export default defineComponent({ setup(props, { slots }) { return () => h("div", {}, slots); } }); El componente Composite usa HelloWorld en su función de setup y llena sus espacios:
// src/components/Composite.js import { defineComponent, h } from "vue"; import HelloWorld from "./HelloWorld"; export default defineComponent({ setup(props, { slots }) { return () => h(HelloWorld, {}, [h("div", {}, ["Div 1"]), h("div", {}, ["Div 2"])]); } });La aplicación usa ambas formas para representar los mismos dos divs:
<template> <!--<img alt="Vue logo" src="./assets/logo.png">--> Works with plain slots <HelloWorld> <div>Div 1</div> <div>Div 2</div> </HelloWorld> Triggers warning when slots are used from other component <Composite> </Composite> </template> <script> import HelloWorld from "./components/HelloWorld"; import Composite from "./components/Composite"; export default { name: "App", components: { HelloWorld, Composite, }, }; </script> <style> </style> El componente Composite activa esta advertencia:
Non-function value encountered for default slot. Prefer function slots for better performance. La misma advertencia no se activa cuando uso HelloWorld solo desde la plantilla.
No entiendo cuál es la diferencia si uso las ranuras de una plantilla o de otro componente.
¿Cuál es el punto de esta advertencia?
¿Hay alguna forma de eliminar esta advertencia?
La advertencia se refiere a la matriz de VNode creada en la función de representación de setup() en Composite.js .
// src/components/Composite.js export default defineComponent({ setup(props, { slots }) { return () => h(HelloWorld, {}, [h("div", {}, ["Div 1"]), h("div", {}, ["Div 2"])]); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ } }); Esto es ineficiente porque la ranura secundaria se procesa antes de que el componente HelloWorld pueda usarla. El espacio secundario se representa esencialmente en el elemento principal y luego se pasa al elemento secundario. Envolver la generación de espacios secundarios en una función difiere el trabajo hasta que se representa el elemento secundario.
No entiendo cuál es la diferencia si uso las ranuras de una plantilla o de otro componente.
@vue/compiler-sfc compila la <template> de SFC en una función de representación, donde las ranuras se pasan como funciones, lo que evita la advertencia que observó.
En lugar de representar la ranura secundaria en la principal (es decir, pasar una matriz de VNodes como el argumento de las slots directamente), envuélvalo en una función:
// src/components/Composite.js export default defineComponent({ setup(props, { slots }) { return () => 👇 h(HelloWorld, {}, () => [h("div", {}, ["Div 1"]), h("div", {}, ["Div 2"])]); } }); Tenga en cuenta que las llamadas h() internas no necesitan este envoltorio de función porque el elemento secundario las procesa todas junto con la ranura predeterminada.